<#--views##${sysName}##${func.viewPath}##${catalogTable.className}Tree.vue-->
<template>
<div style="padding:5px 0px">
    <div v-if="editable" style="padding-top:5px;padding-bottom: 3px;">
    <el-button @click="()=>showAdd${catalogTable.className}FormModal(-1,'')" size="mini">添加根级${catalogTable.tableCaption!''}</el-button>
    </div>
<#if pTable.isLockByMaster>
    <dayu-data-lock :masterLockState="0" v-model:lockState="actionState.masterLockState" :authTag="actionState.authTag" :onChangeState="treeLockStateChange"/><!-- 按master进行锁定时，必须满足1：对整表数据锁定， 或者2：查询条件必须选择一条主表数据 -->
</#if>
    </div>
    <div style="border: solid #eee 1px" :style="{height: treeSize.height}">
    <ul id="${catalogTable.beanName}Tree" class="ztree"></ul>
</div>

<dayu-form-dialog title="${catalogTable.tableCaption!}-属性编辑" :formModal="${catalogTable.beanName}FormModal" <#if (catalogTableConfig.form.formColumnCount!1)==1>:width="500"<#else>:width="800"</#if> @ok='${catalogTable.beanName}FormModalHandleOk'>
  <${catalogTable.className}Form ref="${catalogTable.beanName}Form" :id="${catalogTable.beanName}FormModal.id"
<#if catalogTableConfig.foreignColumn??>:${catalogTableConfig.foreignColumn.varName}='${catalogTableConfig.foreignColumn.varName}'</#if>
    :parentId="${catalogTable.beanName}FormModal.refId" :parentName="${catalogTable.beanName}FormModal.refName" 
  />
</dayu-form-dialog>

<el-dragable-dialog ref="${catalogTable.beanName}ModalRef" title="112-属性编辑" v-model="${catalogTable.beanName}FormModal.visible" class="form-modal" :width="500"  >
    <${catalogTable.className}Form :id="${catalogTable.beanName}FormModal.id" 
      <#if catalogTableConfig.foreignColumn??>:${catalogTableConfig.foreignColumn.varName}='curr${catalogTableConfig.foreignColumn.propName}'</#if><#t>
      :${catalogTableConfig.parentColumn.varName}="${catalogTable.beanName}FormModal.parentId" :${catalogTableConfig.parentColumn.varNameTrimId}Name="${catalogTable.beanName}FormModal.parentName" 
      ref="${catalogTable.beanName}Form" v-if="${catalogTable.beanName}FormModal.visible"/><!-- 增加v-if，每次弹窗会更新值 -->
    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" :loading="${catalogTable.beanName}FormModal.confirmLoading" @click="${catalogTable.beanName}FormModalHandleOk" size="medium">保存</el-button>
      </span>
    </template>
</el-dragable-dialog>
</template>

<script lang="ts" setup>
/*
 * @author: ${author}
 * @date: 2021-10-06 14:18:29
 * @template: dayu-code-builder
*/

import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage } from 'element-plus';
import { FormModal, IForm } from '@/common/FormModal'
import { myutil } from '@/common/dayu-common'
import '@ztree/ztree_v3/js/jquery.ztree.all.js'
import { ActionState } from '@/common/AuthState'
<#if leafTableConfig?? && leafTableConfig.showLeaf==true>
import { ${leafTable.beanName}Service } from '@/api/${sysName}/${leafTable.className}Service';
</#if>
import {${catalogTable.beanName}Service} from '@/api/${sysName}/${catalogTable.className}Service';
import ${catalogTable.className}Form from './${catalogTable.className}Form.vue'

const props = defineProps({
<#if catalogTableConfig.foreignColumn??>
  ${catalogTableConfig.foreignColumn.varName}: ${catalogTableConfig.foreignColumn.jsType},
</#if>
  height: Number,
  editable:{type:Boolean, default: false},
  dragable:{type:Boolean, default: false},
  actionState:{type:Object as PropType<ActionState>, default: new ActionState(false, false, 0xFFFF, 0, 0)},
})
<#if catalogTableConfig.foreignColumn??>
let curr${catalogTableConfig.foreignColumn.propName}: ref(props.${catalogTableConfig.foreignColumn.varName});
</#if>
<#if pTable.isLockByMaster>
async function treeLockStateChange(masterId:number, lockState:number){
  try{
    let response = await ${catalogTable.beanName}Service.changeMasterLockState(lockState);
    return Promise.resolve(lockState);
  }catch(ex:any){
    return Promise.reject(ex);
  }
}
</#if>

const treeSize = computed(()=>{
  let treeHeight = props.height as number;
  if(props.editable) treeHeight -= 50;//减去 添加 按钮的高度
  return{
    height: treeHeight +'px'
  }
});
const ${catalogTable.beanName}Form = ref();
const ${catalogTable.beanName}FormModal = reactive(new FormModal());//表单弹窗

//树形结构
const selectedNode = reactive({ nodeId: '', nodeName:'' });
let ${catalogTable.beanName}ZTree : any;
const curr${catalogTable.className} = reactive({id:<number>NaN, name:''});
let parentTreeNode:any = undefined;

function init${catalogTable.className}Tree() {
  var ztreeSetting = {
    data: {
      simpleData: {
        enable: true
      },
      keep: {
        parent: true //节点属性锁，是否始终保持 isParent = true
      }
    },
    async: {
      enable: true, //异步获取节点数据
      url: "api/base/${catalogTable.beanName}/getChildNodes?<#if catalogTableConfig.foreignColumn??>${catalogTableConfig.foreignColumn.varName}="+curr${catalogTableConfig.foreignColumn.propName}.value+"</#if><#if leafTableConfig?? && leafTableConfig.showLeaf==true>showLeaf=true</#if>",  //获取节点数据的url
      autoParam: ["id=pId"]
    },
    edit: {
      enable: props.editable, //节点可以编辑（需要引入 ztree.all.js，含 edit.js）
      showRemoveBtn: true,
      showRenameBtn: true,
      removeTitle: "删除",
      renameTitle: "编辑",
      drag:{}
    },
    view: {
      selectedMulti: false, //节点不可多选

      addHoverDom(treeId: any, treeNode: any){//用于当鼠标移动到节点上时，显示用户自定义控件，显示隐藏状态同 zTree 内部的编辑、删除按钮，请务必与 setting.view.removeHoverDom 同时使用
        if ($("#btn_add_child_func_"+treeNode.id).length>0) return;
        const IDMark = "_edit";
        let aObj = $("#" + treeNode.tId + IDMark);
        if ( $("#diyBtn_" + treeNode.id).length > 0 ) return;

        let htmlStr = `<span id='diyBtn_space_${r'${treeNode.id}'}' style='padding-left:10px'></span>`+
        `<span class='ztree-my-icon ztree-add-child'    id='btn_add_child_func_${r'${treeNode.id}'}' title='添加下级节点'>`+
        `</span><span class='ztree-my-icon ztree-add-sibling'  id='btn_add_sibling_func_${r'${treeNode.id}'}' title='添加同级节点'></span>`;
        aObj.before(htmlStr);
        let btnChild = $("#btn_add_child_func_" + treeNode.id);
        let btnSibling = $("#btn_add_sibling_func_" + treeNode.id);
        if (btnChild) { //添加下级
          btnChild.on("click", function(){
            parentTreeNode = treeNode;
            let node = myutil.parseTreeNodeId(treeNode.id);
            showAdd${catalogTable.className}FormModal(node.id, treeNode.name);
          });
        }
        if (btnSibling) {//添加同级
          btnSibling.on("click", function(){
            let parentNode = treeNode.getParentNode();
            parentTreeNode = parentNode;
            if(parentNode){
              let node = myutil.parseTreeNodeId(parentNode.id);
              showAdd${catalogTable.className}FormModal(node.id, parentNode.name);
            }else{
              showAdd${catalogTable.className}FormModal(-1, '');
            }
          });
        }
      },
      removeHoverDom(treeId: any, treeNode: any){//用于当鼠标移出节点时，隐藏用户自定义控件，显示隐藏状态同 zTree 内部的编辑、删除按钮，请务必与 addHoverDom 同时使用
        $("#btn_add_child_func_"+treeNode.id).off().remove();
        $("#btn_add_sibling_func_"+treeNode.id).off().remove();
        $("#diyBtn_space_"+treeNode.id).off().remove();
      },
      addDiyDom(treeId: any, treeNode: any){//用于在节点上固定显示用户自定义控件。大数据量的节点加载请注意：在 addDiyDom 中针对每个节点 查找 DOM 对象并且添加新 DOM 控件，肯定会影响初始化性能；如果不是必须使用，建议不使用此功能


      }
    },
    callback: {
      onClick: function (event: any, treeId: any, treeNode: any, clickFlag: any) {
        let nodeId = treeNode.id || '';
        let spIdx = nodeId.indexOf('cat-');
        if (spIdx == 0) {
          selectedNode.nodeId = nodeId;
          curr${catalogTable.className}.id = parseInt(nodeId.substring(4));
          curr${catalogTable.className}.name = treeNode.name;
          emits('${catalogTable.beanName}Click', curr${catalogTable.className});//触发事件
        }
      },
      beforeEditName(treeId: any, treeNode: any) {
        let nodeId = treeNode.id || '';
        if (nodeId.indexOf('cat-') == 0) {
          showEdit${catalogTable.className}FormModal(nodeId.substring(4));
        } else if (nodeId.indexOf('leaf-') == 0) {

        }
        return false;
      },
      beforeRemove(treeId: any, treeNode: any) {
        let nodeId = treeNode.id || '';
        myutil.confirmForDelete(`确认要删除 ${r'${treeNode.name}'} 吗？`).then(async()=>{
          if (nodeId.indexOf('cat-') == 0) {
              await ${catalogTable.beanName}Service.delete${catalogTable.className}(nodeId.substring(4));
              ${catalogTable.beanName}ZTree.removeNode(treeNode, false);
            } else if (nodeId.indexOf('leaf-') == 0) {
              <#if leafTableConfig?? && leafTableConfig.showLeaf==true>
              ${leafTable.beanName}Service.delete${leafTable.className}(nodeId.substring(5));
              ${catalogTable.beanName}ZTree.removeNode(treeNode, false);
              </#if>
            }
        });
        return false;
      },
      onAsyncSuccess(event: any, treeId: any, treeNode: any, msg: any){

      }
    }
  };

  if(${catalogTable.beanName}ZTree){
    ${catalogTable.beanName}ZTree.destroy();
    ${catalogTable.beanName}ZTree = null;
  }

  if(props.editable && props.dragable){
      ztreeSetting.edit.drag = {
        autoExpandTrigger:false,/**拖拽时父节点自动展开是否触发 onExpand 事件回调函数 */
        isCopy: false,
        isMove: true,
        prev: false,
			  next: false,
			  inner: true,
      };

      (ztreeSetting.callback as any).beforeDrag = function(treeId: any, treeNodes: any){
        if(treeNodes.length>1)return false;
        return true;
      };
      (ztreeSetting.callback as any).onDrag = function(event:any, treeId: any, treeNodes: any){
        return true;
      };
      (ztreeSetting.callback as any).beforeDrop = function(treeId: any, treeNodes: any, targetNode: any, moveType: any, isCopy: any){
        let pId = -1;
        if(targetNode == null){
          pId = -1;
        }else{
          let pnode = myutil.parseTreeNodeId(targetNode.id);
          pId = pnode.id;
        }
        let dragNode = treeNodes[0];
        let node = myutil.parseTreeNodeId(dragNode.id);
        let id = node.id;

        ${catalogTable.beanName}Service.changeParent(id, pId).catch((reason:any)=>{
          let msg = reason.errMsg || reason.errorMessage || JSON.stringify(reason);
          ElMessage.error(msg);
        }).finally(()=>{
          reAsyncChildNodes(targetNode);
        });
        return true;
      };
      (ztreeSetting.callback as any).onDrop = function(event: any, treeId: any, treeNodes: any, targetNode: any, moveType: any, isCopy: any){
        return true;
      };
  }
  ${catalogTable.beanName}ZTree = ($.fn as any).zTree.init($('#${catalogTable.beanName}Tree'), ztreeSetting);
  parentTreeNode = undefined;
}

/** 弹出 部门 编辑表单 */
async function showEdit${catalogTable.className}FormModal(id: number) {
  ${catalogTable.beanName}FormModal.showModal(id);//显示表单对话框
}
/** 弹出 部门 添加表单 */
async function showAdd${catalogTable.className}FormModal(parentId: number, parentName:string) {
  ${catalogTable.beanName}FormModal.showModal(undefined, parentId, parentName);//显示表单对话框
}


/**部门表单【确定】按钮点击事件*/
async function ${catalogTable.beanName}FormModalHandleOk() {
  let response = await ${catalogTable.beanName}FormModal.submit(${catalogTable.beanName}Form.value as IForm);
  console.log("after ok button clicked:");
  console.log(response);

  reAsyncChildNodes(parentTreeNode)
}

/**重新加载子节点，如果parentTreeNode为空，则重新初始化树结构 */
function reAsyncChildNodes(parentTreeNode:any){
  if(parentTreeNode){
    ${catalogTable.beanName}ZTree.reAsyncChildNodes(parentTreeNode, "refresh");
  }else{
    emits('${catalogTable.beanName}Click', null);//触发事件
    init${catalogTable.className}Tree(); //重新加载树结构
  }
}

/** 定义事件 */
const emits = defineEmits(['${catalogTable.beanName}Click'])

onMounted(() => {
  init${catalogTable.className}Tree();
});
</script>